package com.yungu.swift.system.sys.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.mapper.IMapper;
import com.yungu.swift.base.model.PageVo;
import com.yungu.swift.base.model.admin.AdminPageParam;
import com.yungu.swift.base.service.impl.BaseServiceImpl;
import com.yungu.swift.system.sys.dao.SysUserOperateLogMapper;
import com.yungu.swift.system.sys.model.dto.SysUserOperateLogDto;
import com.yungu.swift.system.sys.service.SysUserOperateLogService;
import com.yungu.swift.utils.HttpUtils;
import com.yungu.swift.utils.JsonUtils;
import com.yungu.swift.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.*;


/**
 * SysUserOperateLogServiceImpl
 **/
@Slf4j
@Service
public class SysUserOperateLogServiceImpl extends BaseServiceImpl<SysUserOperateLogDto> implements SysUserOperateLogService {

    @Autowired
    private SysUserOperateLogMapper sysUserOperateLogMapper;

    @Override
    protected IMapper<SysUserOperateLogDto> getMapper() {
        return sysUserOperateLogMapper;
    }

//    private static final ExecutorService POOL = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1,
//            15, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024),
//            new ThreadFactoryBuilder().build(), new ThreadPoolExecutor.AbortPolicy());
    private static final ExecutorService POOL = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1,
            100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024),
            new ThreadFactoryBuilder().build(), new ThreadPoolExecutor.AbortPolicy());

    @Override
    public <AdminOperationLogPageParam extends AdminPageParam> ResponseData<PageVo<SysUserOperateLogDto>> queryPage(AdminOperationLogPageParam pageParam) {
        ResponseData<PageVo<SysUserOperateLogDto>> responseData = super.queryPage(pageParam);
        if (responseData.isSuccess() && responseData.getData() != null && CollectionUtils.isNotEmpty(responseData.getData().getItems())) {
            for (SysUserOperateLogDto operationLogDto : responseData.getData().getItems()) {
                if (StringUtils.isEmpty(operationLogDto.getOperationIp())) {
                    continue;
                }
                StringBuffer ipAddress = new StringBuffer(operationLogDto.getOperationIp());
                Future<?> submit = POOL.submit(() -> {
                    try {
                        Map<String, Object> objectMap = HttpUtils.get("http://ip.taobao.com/service/getIpInfo.php?ip=" + operationLogDto.getOperationIp());
                        int status = (Integer) objectMap.get("status");
                        if (status != -1) {
                            Map<String, Object> result = JsonUtils.readValue(String.valueOf(objectMap.get("result")), Map.class);
                            Map<String, Object> data = (Map) result.get("data");
                            ipAddress.append("-")
                                    .append(data.get("country"))
                                    .append(data.get("region"))
                                    .append(data.get("city"))
                                    .append(data.get("county"));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                });
                try {
                    submit.get(250, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
                operationLogDto.setOperationIp(ipAddress.toString());
            }
        }
        return responseData;
    }
}
